<template>
    <view style="height: 100%">
        <movable-area :style="{ width: '100%', height: allHeight + 'px' }">
            <movable-view
                v-for="(item, index) in list"
                :key="item.id"
                :x="0"
                :y="item.y"
                :style="{ height: itemHeight + 'px', width: '100%' }"
                direction="all"
                class="movable-view"
                @touchstart="handleDragStart(index)"
                @change="handleMoving(index, $event)"
                @touchend="handleDragEnd"
            >
                <!-- 这里可以放置步骤的详细内容 -->
                <view style="background-color: aqua; padding: 20rpx 0">{{ item.desc }}</view>
            </movable-view>
        </movable-area>
    </view>
</template>

<script>
export default {
    data() {
        return {
            list: [],
            cloneList: [],

            activeIndex: -1, // 选中
            oldIndex: -1,

            moveToIndex: -1, // 移动

            allHeight: 300,

            itemHeight: 50
        };
    },

    created() {
        for (let i = 0; i < 12; i++) {
            let info = {
                id: i,
                desc: "测试" + i
            };
            this.list.push(info);
        }
        this.allHeight = 12 * this.itemHeight;
        this.initList(this.list);
    },

    methods: {
        deepCopy(source) {
            return JSON.parse(JSON.stringify(source));
        },

        initList(list = []) {
            const newList = this.deepCopy(list);
            this.list = newList.map((item, index) => {
                return {
                    ...item,
                    y: index * this.itemHeight,
                    key: Math.random() + index
                };
            });
            //拷贝一份初始list值
            this.cloneList = this.deepCopy(this.list);
        },

        // 拖拽开始
        handleDragStart(index) {
            this.activeIndex = index;
            this.oldIndex = index;
        },
        handleMoving(index, e) {
            if (e.detail.source !== "touch") return;
            const { x, y } = e.detail;
            const currentY = Math.floor((y + this.itemHeight / 2) / this.itemHeight);

            this.moveToIndex = Math.min(currentY, this.list.length - 1);

            //更新移动后的位置
            if (this.oldIndex !== this.moveToIndex && this.oldIndex !== -1 && this.moveToIndex !== -1) {
                const newList = this.deepCopy(this.cloneList);
                //交换位置
                newList.splice(this.moveToIndex, 0, ...newList.splice(this.activeIndex, 1));

                this.list.forEach((item, index) => {
                    if (index !== this.activeIndex) {
                        const itemIndex = newList.findIndex((val) => val.id === item.id);
                        item.y = itemIndex * this.itemHeight;
                    }
                });
                this.oldIndex = this.moveToIndex;
            }
        },
        handleDragEnd(e) {
            if (this.moveToIndex !== -1 && this.activeIndex !== -1 && this.moveToIndex !== this.activeIndex) {
                this.cloneList.splice(this.moveToIndex, 0, ...this.cloneList.splice(this.activeIndex, 1));
            }

            // 重新排序下更新后的位置。
            this.initList(this.cloneList);

            this.activeIndex = -1;
            this.oldIndex = -1;
            this.moveToIndex = -1;
        }
    }
};
</script>
